package com.jeesite.modules.dataScreen.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.jeesite.modules.dataScreen.dao.JtdnZbDao;
import com.jeesite.modules.dataScreen.dao.TianbaoDao;
import com.jeesite.modules.dataScreen.dao.sjtbdb.SjtbDbDao;
import com.jeesite.modules.dataScreen.dao.themedb.ThemeDbDao;
import com.jeesite.modules.dataScreen.entity.Tianbao;
import com.jeesite.modules.dataScreen.utils.DatePair;
import com.jeesite.modules.dataScreen.web.vo.NameValueVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * @author: mumu
 * @date: 2024/5/13 11:12
 */
@Slf4j
public class BaseController {

    public static final Integer ZERO = 0;

    public static final String VALUE = "value";
    public static final String UNIT  = "unit";

    @Resource
    SjtbDbDao  sjtbDbDao;
    @Resource
    ThemeDbDao themeDbDao;
    // @Resource
    // IndexsDao  indexsDao;
    @Resource
    JtdnZbDao  jtdnZbDao;
    @Resource
    TianbaoDao tianbaoDao;

    public static DatePair jd(Integer region) {
        if (region == null) {
            return new DatePair();
        }
        DateTime dateTime = null;
        if (region == 4) {
            dateTime = DateUtil.parseDate(StrUtil.format("{}-01-01", DateUtil.thisYear() + 1));
        } else {
            dateTime = DateUtil.parseDate(StrUtil.format("{}-{}-01", DateUtil.thisYear(), (region + 1) * 3 - 1));
        }
        return new DatePair(
                DateUtil.beginOfDay(DateUtil.beginOfQuarter(dateTime)),
                DateUtil.endOfDay(DateUtil.endOfQuarter(dateTime)));
    }

    public static DatePair yf(Integer region) {
        if (region == null) {
            return new DatePair();
        }
        DateTime dateTime = DateUtil.date();
        if (region == 12) {
            dateTime = DateUtil.parseDate(StrUtil.format("{}-01-01", DateUtil.thisYear() + 1));
        } else {
            dateTime = DateUtil.parseDate(StrUtil.format("{}-{}-01", DateUtil.thisYear(), region + 1));
        }
        return new DatePair(
                DateUtil.beginOfDay(DateUtil.beginOfMonth(dateTime)),
                DateUtil.endOfDay(DateUtil.endOfMonth(dateTime)));
    }

    public Optional<String> getTianbaoValue(String indexName) {
        return getTianbaoValue(indexName, null, new DatePair()).map(Tianbao::getIndexValue);
    }

    public Optional<String> getTianbaoValue(String indexName, String tbdw) {
        return getTianbaoValue(indexName, tbdw, new DatePair()).map(Tianbao::getIndexValue);
    }

    public Optional<Tianbao> getTianbaoValue(String indexName, String tbdw, DatePair datePair) {
        // Optional<Tianbao> opt = Optional.ofNullable(themeDbDao.tianbaoValue(indexName, tbdw,
        //                                                                  DateUtil.formatDateTime(datePair.getStartTime()), DateUtil.formatDateTime(datePair.getEndTime())))
        //                              ;
        // if (!opt.isPresent()) {
        //     return Optional.ofNullable(sjtbDbDao.tianbaoValue(indexName, tbdw,
        //                                                       DateUtil.formatDateTime(datePair.getStartTime()), DateUtil.formatDateTime(datePair.getEndTime())))
        //                    ;
        // }
        // return opt;
        return Optional.ofNullable(sjtbDbDao.tianbaoValue(indexName, tbdw,
                                                          DateUtil.formatDateTime(datePair.getStartTime()), DateUtil.formatDateTime(datePair.getEndTime())))
                ;
    }

    @Deprecated
    public Map<String, JSONObject> allData() {
        Map<String, JSONObject> result = new HashMap<>();
        List<Object> list = EasyExcel
                .read(ResourceUtil.getStream("xlsx/高速公路数据需求表（路网公司5.16）.xlsx"))
                .sheet()
                .doReadSync();

        // for (Object o : list) {
        //     LinkedHashMap<Integer, Object> map       = (LinkedHashMap<Integer, Object>) o;
        //     String                         indexName = StrUtil.toString(map.get(1));
        //     JSONObject                     jo        = new JSONObject();
        //     jo.put(VALUE, map.get(2));
        //     jo.put(UNIT, map.get(3));
        //     put(result, "高速公路-" + indexName, jo);
        //     put(result, indexName, jo);
        // }
        //
        // List<Object> list2 = EasyExcel
        //         .read(ResourceUtil.getStream("xlsx/普通公路数据需求表0516.xlsx"))
        //         .sheet()
        //         .doReadSync();
        //
        // for (Object o : list2) {
        //     LinkedHashMap<Integer, Object> map       = (LinkedHashMap<Integer, Object>) o;
        //     String                         indexName = StrUtil.toString(map.get(2));
        //     JSONObject                     jo        = new JSONObject();
        //     jo.put(VALUE, map.get(3));
        //     jo.put(UNIT, map.get(4));
        //     put(result, "普通公路-" + indexName, jo);
        //     put(result, indexName, jo);
        // }
        //
        // List<Object> list3 = EasyExcel
        //         .read(ResourceUtil.getStream("xlsx/交通运输体征指标2.0.xlsx"))
        //         .sheet()
        //         .doReadSync();
        //
        // for (Object o : list3) {
        //     LinkedHashMap<Integer, Object> map       = (LinkedHashMap<Integer, Object>) o;
        //     String                         indexName = StrUtil.toString(map.get(4));
        //     JSONObject                     jo        = new JSONObject();
        //     jo.put(VALUE, map.get(6));
        //     jo.put(UNIT, map.get(5));
        //     put(result, indexName, jo);
        // }
        //
        // List<Object> list4 = EasyExcel
        //         .read(ResourceUtil.getStream("xlsx/交通运输体征指标2.0.xlsx"))
        //         .sheet(1)
        //         .doReadSync();
        //
        // for (Object o : list4) {
        //     LinkedHashMap<Integer, Object> map       = (LinkedHashMap<Integer, Object>) o;
        //     String                         indexName = StrUtil.toString(map.get(4));
        //     JSONObject                     jo        = new JSONObject();
        //     jo.put(VALUE, map.get(5));
        //     jo.put(UNIT, "");
        //     put(result, indexName, jo);
        // }
        //
        // List<Indexs> indexsList = indexsDao.selectList(Wrappers.emptyWrapper());
        // for (Indexs o : indexsList) {
        //     String     indexName = o.getName();
        //     JSONObject jo        = new JSONObject();
        //     jo.put(VALUE, o.getStaticValue());
        //     jo.put(UNIT, o.getUnit());
        //     put(result, indexName, jo);
        // }

        // List<JtdnZb> indexsList = jtdnZbDao.selectList(Wrappers.emptyWrapper());
        // for (JtdnZb o : indexsList) {
        //     String     indexName = o.getZbmc();
        //     JSONObject jo        = new JSONObject();
        //     jo.put(VALUE, o.getSjzWb());
        //     jo.put(UNIT, o.getSjdw());
        //     put(result, indexName, jo);
        // }

        // List<Tianbao> indexsList = themeDbDao.tianbao();
        // for (Tianbao o : indexsList) {
        //     String     indexName = o.getIndexName();
        //     JSONObject jo        = new JSONObject();
        //     jo.put(VALUE, o.getIndexValue());
        //     // jo.put(UNIT, null);
        //     put(result, indexName, jo);
        // }

        log.info("read xlsx");

        return result;
    }

    public static void put(Map<String, JSONObject> result, String key, JSONObject value) {
        if (result.containsKey(key)) {
            log.warn("dumpkey {}", key);
        }
        result.put(key, value);
    }

    public static <O, T> T safeGet(O value, Function<O, T> getFun, T defaultValue) {
        if (value != null) {
            T apply = getFun.apply(value);
            if (apply != null) {
                return apply;
            }
        }
        return defaultValue;
    }

    public static Map<String, Field> b(Class<?> clazz) {
        Map<String, Field> map = new HashMap<>();
        ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                ApiModelProperty apiModelProperty = AnnotationUtils.getAnnotation(field, ApiModelProperty.class);
                if (apiModelProperty != null) {
                    String name = apiModelProperty.value();
                    map.put(name, field);
                }
            }
        });
        return map;
    }

    public <T> void fillDataByTiaoBao(Map<String, JSONObject> a, Class<T> clazz, T value) {
        fillDataByTiaoBao(a, clazz, value, new DatePair());
    }

    public <T> void fillDataByTiaoBao(Map<String, JSONObject> a, Class<T> clazz, T value, DatePair datePair) {
        Map<String, Field> fieldMap = b(clazz);
        fieldMap.forEach(new BiConsumer<String, Field>() {
            @Override
            public void accept(String s, Field field) {
                // JSONObject v = a.get(s);
                try {
                    Tianbao v = getTianbaoValue(s, null, datePair).orElse(null);
                    if (v != null) {
                        // Object vv = v.get(VALUE);
                        Object vv = v.getIndexValue();
                        if (vv != null) {
                            BeanUtil.setFieldValue(value, field.getName(), vv);
                        }
                    } else {
                        boolean flag = false;
                        if (String.class.equals(field.getType())) {
                            BeanUtil.setFieldValue(value, field.getName(), "0");
                            flag = true;
                        }
                        if (Integer.class.equals(field.getType())) {
                            BeanUtil.setFieldValue(value, field.getName(), 0);
                            flag = true;
                        }
                        if (Long.class.equals(field.getType())) {
                            BeanUtil.setFieldValue(value, field.getName(), 0L);
                            flag = true;
                        }
                        if (Double.class.equals(field.getType())) {
                            BeanUtil.setFieldValue(value, field.getName(), 0D);
                            flag = true;
                        }
                        // if (flag) {
                        //     Tianbao tianbao = new Tianbao();
                        //     tianbao.setTbdate(new Date());
                        //     tianbao.setIndexValue("0");
                        //     tianbao.setIndexName(s);
                        //     tianbaoDao.insert(tianbao);
                        // }
                    }
                } catch (Exception e) {
                    log.error("set error: {}", e.getMessage());
                }
            }
        });

    }

    public static Integer nullToZero(Integer value) {
        if (value == null) {
            return ZERO;
        }

        return value;
    }

    public static <T> T getValue(JSONArray jsonArray, String name, T defaultValue) {
        Object one = CollUtil.findOne(jsonArray, new Filter<Object>() {
            @Override
            public boolean accept(Object o) {
                JSONObject jo = (JSONObject) o;
                return StrUtil.equals(jo.getString("name"), name);
            }
        });
        if (one != null) {
            JSONObject jo = (JSONObject) one;
            try {
                return (T) jo.get("value");
            } catch (ClassCastException e) {
                log.error("获取数据异常", e);
            }
        }
        return defaultValue;
    }

    public String getValue2(JSONArray jsonArray, String name, String defaultValue) {
        return getTianbaoValue(name).orElse(defaultValue);
    }

    public String bwtJkzb() {
        try {
            return sjtbDbDao.bwtJkzb();
        } catch (Exception e) {
            return ResourceUtil.readStr("data/yushun.json", StandardCharsets.UTF_8);
        }
    }

    public static List<NameValueVo> top(List<NameValueVo> list, Integer top) {
        CollUtil.sort(list, (o1, o2) -> CompareUtil.compare(
                NumberUtil.toBigDecimal(o2.getValue()),
                NumberUtil.toBigDecimal(o1.getValue()),
                false));
        return CollUtil.sub(list, 0, top);
    }

    public static void fillFieldInfo(Object e, Map<String, Object> fieldMean) {
        ReflectionUtils.doWithFields(e.getClass(), field -> {
            ApiModelProperty apiModelProperty = AnnotationUtils.findAnnotation(field, ApiModelProperty.class);
            if (apiModelProperty != null) {
                fieldMean.put(field.getName(), apiModelProperty.value());
            }
        });
    }
}
